home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 3 / Cream of the Crop 3.iso / comm / wnos5src.zip / DOMCLI.C < prev    next >
Text File  |  1993-11-20  |  15KB  |  606 lines

  1. #include <ctype.h>
  2. #include <io.h>
  3. #include <dos.h>
  4.  
  5. #include "global.h"
  6. #include "config.h"
  7. #include "domain.h"
  8. #include "socket.h"
  9. #include "netuser.h"
  10. #include "files.h"
  11. #include "cmdparse.h"
  12. #include "ip.h"                /* for use with autoping entries */
  13.  
  14. struct dserver *Dlist = NULLDOM;
  15.  
  16. #ifdef ENH
  17. static struct rr *Rrlist[NRLIST];
  18. #endif
  19.  
  20. int Dhaveaa = 1;
  21. int DBloaded = 0;
  22. int Db_initialize = 0;
  23. int DTranslate = 0;
  24. int DVerbose = 1;
  25. int Cwrite = 0;
  26. int16 Dcache_size = 20;
  27.  
  28. static int16 Dtimeout = 60;
  29. int16 Dretries = 1;
  30.  
  31. char *Dsuffix = NULLCHAR;
  32.  
  33. int Dstypes[] = {
  34.     TYPE_SOA,
  35.     TYPE_NS,
  36.     TYPE_MX,
  37.     TYPE_MD,
  38.     TYPE_MF,
  39.     TYPE_CNAME,
  40.     TYPE_PTR,
  41.     TYPE_A,
  42.     TYPE_MB,
  43.     TYPE_MG,
  44.     TYPE_MR,
  45.     TYPE_NULL,
  46.     TYPE_WKS,
  47.     TYPE_HINFO,
  48.     TYPE_MINFO,
  49.     TYPE_TXT,
  50.     0
  51. };
  52.  
  53. /*----------------------------------------------------------------------*
  54. * list the cache entries                                                *
  55. *-----------------------------------------------------------------------*/
  56. int
  57. docachelist(int argc,char **argv,void *p)
  58. {
  59.     int i;
  60.     Cache *cap = cache;
  61.  
  62.     static char *Apstates[] = {
  63.         "",
  64.         "Bad",
  65.         "Suspect",
  66.         "Good",
  67.         "Active",
  68.         "Idle"
  69.     };
  70.  
  71.    tputs("Address          Status  Route   Setping Name\n");
  72.  
  73.    for (i = 0; i < Dcache_size; i++) {
  74.       if(i == Dcache_size) {
  75.          break;
  76.       }
  77.       if(cap->ti) {
  78.          char buf[20];
  79.  
  80.          sprintf(buf,"%u.%u.%u.%u",            /* always print the ip-address */
  81.             hibyte(hiword(cap->address)),   /* even if DTranslate is set   */
  82.             lobyte(hiword(cap->address)),
  83.             hibyte(loword(cap->address)),
  84.             lobyte(loword(cap->address)));
  85.  
  86.          tprintf("%-17s%-8s%-8s%-8s%s\n",
  87.             buf,
  88.             cap->type ? "Invalid" : "Valid",
  89.             Apstates[cap->state],
  90.             Apstates[cap->proc_run],
  91.             cap->name);
  92.       }
  93.       cap++;
  94.    }
  95.    return 0;
  96. }
  97.  
  98. static int
  99. docachegarb(int argc,char **argv,void *p)
  100. {
  101.     int i;
  102.     Cache *cap = cache;
  103.  
  104.     semwait(&Cwrite,1);
  105.  
  106.     for(i = 0; i < Dcache_size; i++) {
  107.         if(cap->type == Missing || cap->address == 0) {
  108.             cap->ti = 0;
  109.             memset(cap->name,0,5);
  110.         }
  111.         cap++;
  112.     }
  113.     semrel(&Cwrite);
  114.     return 0;
  115. }
  116.  
  117. /*----------------------------------------------------------------------*
  118. * change the cache size
  119. *-----------------------------------------------------------------------*/
  120. static int
  121. docachesize(int argc,char **argv,void *p)
  122. {
  123. int16 result = 0, newsize = Dcache_size;
  124.  
  125.    if((result = setintrc(&newsize,"DOM cache size",argc,argv,2,50)) == 0) {
  126.        if(argc > 1 && newsize > 0){
  127.           semwait(&Cwrite,1);               /* lock again                   */
  128.           Dcache_size = newsize;
  129.           xfree(cache);
  130.           cache = cxallocw(sizeof(Cache),(newsize + 2));
  131.           semrel(&Cwrite);
  132.        }
  133.    }
  134.    return (int)result;
  135. }
  136.  
  137. static int
  138. doadds(int argc,char **argv,void *p)
  139. {
  140.     struct dserver *dp;
  141.     int32 address;
  142.  
  143.     if((address = resolve(argv[1])) == 0) {
  144.         tprintf(Badhost,argv[1]);
  145.         return 1;
  146.     }
  147.     if(address == Ip_addr) {
  148.         tputs("Use: start domain\n");
  149.         return 1;
  150.     }
  151.     for(dp = Dlist; dp != NULLDOM; dp = dp->next) {
  152.         if(dp->address == address) {
  153.             break;
  154.         }
  155.     }
  156.     if(dp == NULLDOM) {
  157.         dp = mxallocw(sizeof(struct dserver));
  158.         dp->address = address;
  159.  
  160.         dp->next = Dlist;
  161.         Dlist = dp;
  162.     }
  163.     /* Pick a wait time for response: it takes about 15 sec on my AT
  164.      * to scan trough the domain.txt file. Taking 3 scans (max)
  165.      * and giving a little strech to the channel i come to 60 secs */
  166.     dp->srtt = dp->timeout = (argc < 3) ? Dtimeout * 1000L : atoi(argv[2]) * 1000L;
  167.     dp->mdev = 0;
  168.     Dhaveaa = 0;             /* another is also responsible */
  169.     return 0;
  170. }
  171.  
  172. static int
  173. dodfile(int argc,char **argv,void *p)
  174. {
  175.     if(argc < 2) {
  176.         if(Dfile != NULLCHAR) {
  177.             tprintf("%s\n",Dfile);
  178.         }
  179.     } else {
  180.         if(access(argv[1],0) == 0) {
  181.             xfree(Dfile);
  182.             Dfile = strxdup(argv[1]);
  183.         } else {
  184.             tputs("No such domain file\n");
  185.             return -1;
  186.         }
  187.     }
  188.     return 0;
  189. }
  190.  
  191. static int
  192. dodropds(int argc,char **argv,void *p)
  193. {
  194.     struct dserver *dp, *dptmp = NULLDOM;
  195.     int32 addr;
  196.  
  197.     if((addr = resolve(argv[1])) == 0) {
  198.         tprintf(Badhost,argv[1]);
  199.     } else {
  200.         for(dp = Dlist; dp != NULLDOM; dptmp = dp, dp = dp->next) {
  201.             if(dp->address == addr) {
  202.                 if(dptmp != NULLDOM) {
  203.                     dptmp->next = dp->next;
  204.                 } else {
  205.                     Dlist = dp->next;
  206.                 }
  207.                 xfree(dp);
  208.  
  209.                 if(Dlist == NULLDOM) {
  210.                     Dhaveaa = 1;
  211.                 }
  212.                 return 0;
  213.             }
  214.         }
  215.     }
  216.     return -1;
  217. }
  218.  
  219. static int
  220. dolistds(int argc,char **argv,void *p)
  221. {
  222.     struct dserver *dp;
  223.  
  224.     tputs("Server           srtt    mdev    timeout queries responses timeouts\n");
  225.  
  226.     for(dp = Dlist; dp != NULLDOM; dp = dp->next) {
  227.         tprintf("%-17s%-8lu%-8lu%-8lu%-8lu%-10lu%-8lu\n",
  228.             inet_ntoa(dp->address),
  229.             dp->srtt,dp->mdev,dp->timeout,
  230.             dp->queries,dp->responses,dp->missers);
  231.     }
  232.     return 0;
  233. }
  234.  
  235. #ifdef ENH
  236. static int
  237. doload(int argc,char **argv,void *p)
  238. {
  239.     FILE *dbase;
  240.     int type, numbscan = 0, numbload = 0;
  241.     long rrsize = 0;
  242.     struct rr *rrp, *rrl, *db_SOA;
  243.     struct rr_memory *memory;
  244.     char *arg[2];
  245.     char Recload[] = "Number of %srecords scanned %d loaded %d\n";
  246.  
  247.     arg[0] = NULLCHAR;
  248.     arg[2] = NULLCHAR;
  249.  
  250.     if((dbase = Fopen((argc < 3) ? Dfile : argv[1],READ_TEXT,0,1)) == NULLFILE) {
  251.         return 1;
  252.     }
  253.     memory = mxallocw(sizeof(struct rr_memory));
  254.  
  255.     db_SOA = NULLRR;
  256.  
  257.     if(Lorigin == NULLDLIST) {
  258.         Lorigin = mxallocw(sizeof(struct dlist));
  259.         Lorigin->name = ""; /* start with empty domain name */
  260.         Db_initialize = 1;
  261.         while((rrp = get_rr(dbase,memory)) != NULLRR) {
  262.             type = rrp->type;
  263.             numbscan++;
  264.             numbload++;
  265.             rrsize += (long)rrp->rdlength;
  266.             if(type == TYPE_SOA) {
  267.                 db_SOA = rrp;   /* save for reference */
  268.             } else {
  269.                 rrp->soarec = db_SOA;
  270.             }
  271.             if(Rrlist[type] == NULLRR) {
  272.                 Rrlist[type] = rrp; /* initialize linked list */
  273.                 Rrlistl[type] = rrp;
  274.             } else {
  275.                 Rrlistl[type]->next = rrp;
  276.                 Rrlistl[type] = rrp; /* append to linked list */
  277.             }
  278.         }
  279.         /* Lorigin stayes as a list of loaded domain origin names.
  280.          * it is refered to in rrp->origins loaded in memory.
  281.          * having a common origin saves significantly in used
  282.          * memory oposed to giving every record a copy of that
  283.          * origin. Domain save will reconstruct $origin statements.
  284.          */
  285.         tprintf(Recload,"",numbscan,numbload);
  286.         tprintf("Memory record size %d extra %ld\n",sizeof(struct rr),rrsize);
  287.         Db_initialize = 0;
  288.         Dorigin = NULLCHAR; /* not loading anymore */
  289.         DBloaded = 1;       /* disable domain file access */
  290.     } else {
  291.         Db_initialize = 1;
  292.         while((rrp = get_rr(dbase,memory)) != NULLRR) {
  293.             numbscan++;
  294.             type = rrp->type;
  295.             if(type == TYPE_SOA) {
  296.                 db_SOA = rrp;   /* save for reference */
  297.             } else {
  298.                 rrp->soarec = db_SOA;
  299.             }
  300.             if(add_rr(NULLFILE,rrp)) {
  301.                 free_rr(rrp);
  302.             } else {
  303.                 numbload++;
  304.             }
  305.         }
  306.         tprintf(Recload,"additional ",numbscan,numbload);
  307.         Db_initialize = 0;
  308.         Dorigin = NULLCHAR; /* not loading anymore */
  309.         Fclose(dbase);
  310.         xfree(memory);
  311.         return 0;
  312.     }
  313.     Fclose(dbase);
  314.     xfree(memory->dorigin);
  315.     xfree(memory);
  316.     if((rrp = Rrlist[TYPE_NS]) != NULLRR) {
  317.         rrl = rrp;
  318.         while(rrl != NULLRR) {
  319.             arg[1] = rrl->rdata.name;
  320.             doadds(2,arg,p);
  321.             rrl = rrl->next;
  322.         }
  323.     }
  324.     return 0;
  325. }
  326. #endif
  327.  
  328. #ifdef ENH
  329. static int
  330. donslookup(int argc,char **argv,void *p)
  331. {
  332.     int i, len, type = 0;
  333.     int16 flags = DOM_DORECURSE | DOM_CANRECURSE; /* Recursion desired */
  334.     int32 address;
  335.     char *buf;
  336.     struct dhdr *dhdr;
  337.     struct mbuf *bp;
  338.  
  339.     if((address = resolve(argv[1])) == 0) {
  340.         tprintf(Badhost,argv[1]);
  341.         return 1;
  342.     }
  343.     if(isdigit(*argv[2])) {
  344.         type = atoi(argv[2]);
  345.         if(type > 255) {
  346.             type = 0;
  347.         }
  348.     } else {
  349.         for(i = 0; i < NRLIST; i++) {
  350.             if(stricmp(argv[2],type2str(i)) == 0) {
  351.                 type = i;
  352.                 break;
  353.             }
  354.         }
  355.     }
  356.     if(type == 0) {
  357.         tprintf("Unknown record type %s\n",argv[2]);
  358.         return 1;
  359.     }
  360.     dhdr = bld_dhdr(QUERY,QUERY,flags,NO_ERROR,argv[3],CLASS_IN,type);
  361.     buf = mxallocw(512);
  362.     len = res_mkbuf(dhdr,buf,512);
  363.     free_dhdr(dhdr);
  364.  
  365.     for(;;) {
  366.         if(sendquery(address,buf,len,&bp,Dtimeout * 1000) > 0) {
  367.             dhdr = mxallocw(sizeof(struct dhdr));
  368.             ntohdomain(dhdr,&bp);
  369.             proc_answer(dhdr,NULLDOM,NULLFILE);
  370.             free_dhdr(dhdr);
  371.             tputs("NS lookup: host added\n");
  372.         } else {
  373.             tputs("NS lookup: timeout\n");
  374.         }
  375.         break;
  376.     }
  377.     return 0;
  378. }
  379. #endif
  380.  
  381. static int
  382. doretries(int argc,char **argv,void *p)
  383. {
  384.     return setintrc(&Dretries,"DOM retries",argc,argv,1,10);
  385. }
  386.  
  387. #ifdef ENH
  388. static int
  389. dosave(argc,argv,pp)
  390. int argc;
  391. char *argv[];
  392. void *pp;
  393. {
  394.     FILE *dbase;
  395.     int i, j;
  396.     struct rr *rrp;
  397.     struct dlist *llist;
  398.     char *p;
  399.  
  400.     if((dbase = Fopen((argc < 3) ? "/domain.new" : argv[1],WRITE_TEXT,0,1)) == NULLFILE)
  401.         return 1;
  402.     if((llist = Lorigin) != NULLDLIST) {
  403.         while(llist != NULLDLIST) {
  404.             fprintf(dbase,"$origin\t%s\n",llist->name);
  405.             for(i = 0, j = Dstypes[i]; (j = Dstypes[i]) != 0; i++)  {
  406.                 if((rrp = Rrlist[j]) != NULLRR) {
  407.                     while(rrp != NULLRR) {
  408.                         if((*llist->name == '\0')
  409.                           && (rrp->origin == NULLCHAR)) {
  410.                             if(rrp->type != TYPE_A)
  411.                                 put_rr(dbase,rrp,0);
  412.                             else if(rrp->rdata.addr != 0)                                put_rr(dbase,rrp,0);
  413.                         } else if(rrp->origin == llist->name) {
  414.                             if(rrp->type != TYPE_A)
  415.                                 put_rr(dbase,rrp,0);
  416.                             else
  417.                                 if( rrp->rdata.addr != 0)
  418.                                     put_rr(dbase,rrp,0);
  419.                         }
  420.                         rrp = rrp->next;
  421.                     }
  422.                 }
  423.             }
  424.             llist = llist->next;
  425.         }
  426.     } else for(i = 0, j = Dstypes[i]; (j = Dstypes[i]) != 0; i++)  {
  427.         p = NULLCHAR;
  428.         if((rrp = Rrlist[j]) != NULLRR) {
  429.             while(rrp != NULLRR) {
  430.                 if(rrp->name[strlen(rrp->name) - 1] != '.') {
  431.                     if(p == NULLCHAR && rrp->origin != NULLCHAR)
  432.                         fprintf(dbase,"$origin %s\n",rrp->origin);
  433.                     if(p != NULLCHAR && rrp->origin == NULLCHAR)
  434.                         fputs("$origin \n",dbase);
  435.                     if(p != NULLCHAR && rrp->origin != NULLCHAR)
  436.                         if(stricmp(p,rrp->origin))
  437.                             fprintf(dbase,"$origin %s\n",rrp->origin);
  438.                     p = rrp->origin;
  439.                 }
  440.                 if(rrp->type != TYPE_A)
  441.                     put_rr(dbase,rrp,0);
  442.                 else
  443.                    if( rrp->rdata.addr != 0)
  444.                     put_rr(dbase,rrp,0);
  445.                 rrp = rrp->next;
  446.             }
  447.         }
  448.     }
  449.     fclose(dbase);
  450.     return 0;
  451. }
  452. #endif
  453.  
  454. static int
  455. dosuffix(int argc,char **argv,void *p)
  456. {
  457.     if(argc < 2){
  458.         if(Dsuffix != NULLCHAR) {
  459.             tprintf("%s\n",Dsuffix);
  460.         }
  461.     } else {
  462.         if(strcmp(argv[1],"none") == 0) {
  463.             xfree(Dsuffix);
  464.             Dsuffix = NULLCHAR; /* clear out suffix */
  465.         } else {
  466.             int i = strlen(argv[1]) - 1;
  467.             xfree(Dsuffix);
  468.             Dsuffix = mxallocw(i + 3);
  469.             strcpy(Dsuffix,argv[1]);
  470.             if(argv[1][i] != '.') {
  471.                 strcat(Dsuffix,".");
  472.             }
  473.         }
  474.     }
  475.     return 0;
  476. }
  477.  
  478. static int
  479. dotimeout(int argc,char **argv,void *p)
  480. {
  481.     return setintrc(&Dtimeout,"DOM timeout",argc,argv,15,600);
  482. }
  483.  
  484. static int
  485. dotranslate(int argc,char **argv,void *p)
  486. {
  487.     return setbool(&DTranslate,"DOM translate",argc,argv);
  488. }
  489.  
  490. static int
  491. doverbose(int argc,char **argv,void *p)
  492. {
  493.     return setbool(&DVerbose,"DOM verbose",argc,argv);
  494. }
  495.  
  496. #ifdef ENH
  497. static int
  498. dozoneinit(int argc,char **argv,void *p)
  499. {
  500.     struct dhdr *dhdr;
  501.     struct dserver *dp;
  502.     struct sockaddr_in server;
  503.     int32 address;
  504.     int16 flags;
  505.     char *buf, *bootname, *domainname, *name = argv[1];
  506.     int len, s, resp;
  507.     struct mbuf *bp;
  508.     FILE *fp;
  509.  
  510.     if(*name == '[') {
  511.         address = aton(name+1);
  512.     } else {
  513.         if(isaddr(name)) {
  514.             address = aton(name);
  515.         } else {
  516.             tprintf("Can't resolve %s currently\n",argv[1]);
  517.             return 1;
  518.         }
  519.     }
  520.     dp = mxallocw(sizeof(struct dserver));
  521.     dp->srtt = dp->timeout = Dtimeout * 1000;
  522.     dp->mdev = 0;
  523.  
  524.     DBloaded = 1;                           /* disable domain file access */
  525.     bootname = (argc > 2) ? argv[2] : "/domain.txt";
  526.     domainname = (argc > 3) ? argv[3] : "/domain.new";
  527.  
  528.     /* do zoneinit from remote server */
  529.     server.sin_family = AF_INET;
  530.     server.sin_port = IPPORT_DOMAIN;
  531.     server.sin_addr.s_addr = address;
  532.  
  533.     flags = DOM_DORECURSE | DOM_CANRECURSE;         /* Recursion desired */
  534.     buf = mxallocw(512);
  535.     dhdr = bld_dhdr(QUERY,ZONEINIT,flags,NO_ERROR,bootname,CLASS_IN,TYPE_ANY);
  536.     len = res_mkbuf(dhdr,buf,512);
  537.     bp = qdata(buf,(int16)len);
  538.  
  539.     if((fp = Fopen(domainname,WRITE_TEXT,0,1)) != NULLFILE) {
  540.         if((s = socket(AF_INET,SOCK_DGRAM,0)) != -1) {
  541.             send_mbuf(s,bp,0,(char *)&server,SOCKSIZE);
  542.  
  543.             for(;;) {
  544.                 alarm(dp->timeout);
  545.                 resp = recv_mbuf(s,&bp,0,NULLCHAR,0);
  546.                 alarm(0L);
  547.                 if(resp == -1) {
  548.                     break;
  549.                 }
  550.                 ntohdomain(dhdr,&bp);
  551.                 proc_answer(dhdr,dp,fp);
  552.             }
  553.             close_s(s);
  554.         }
  555.         Fclose(fp);
  556.     }
  557.     xfree(buf);
  558.     free_dhdr(dhdr);
  559.     xfree(dp);
  560.     DBloaded = 0;
  561.     return 0;
  562. }
  563. #endif
  564.  
  565. static int
  566. docache(int argc,char **argv,void *p)
  567. {
  568.     struct cmds Dcachecmds[] = {
  569.        "garb",     docachegarb,  0, 0, NULLCHAR,
  570.        "list",   docachelist,  0, 0, NULLCHAR,
  571.        "size",   docachesize,  0, 0, NULLCHAR,
  572.        NULLCHAR,
  573.     };
  574.     return subcmd(Dcachecmds,argc,argv,p);
  575. }
  576.  
  577. int
  578. dodomain(int argc,char **argv,void *p)
  579. {
  580.     struct cmds Dcmds[] = {
  581.         "add",        doadds,     0,       2, "domain add <server> [<timeout>]",
  582.         "cache",    docache,    0,       0, NULLCHAR,
  583.         "dfile",    dodfile,    0,       0, NULLCHAR,
  584.         "drop",        dodropds,   0,       2, "domain drop <server>",
  585.         "list",      dolistds,   0,       0, NULLCHAR,
  586. #ifdef ENH
  587.         "load",     doload,     0,       0, "domain load [<filename>]",
  588.         "nslookup", donslookup, 1024, 4, "domain nslookup <server> <record type> <name>",
  589. #endif
  590.         "retries",  doretries,  0,       0, NULLCHAR,
  591. #ifdef ENH
  592.         "save",     dosave,     0,    0, "domain save [<filename>]",
  593. #endif
  594.         "suffix",   dosuffix,   0,    0, NULLCHAR,
  595.         "timeout",  dotimeout,  0,    0, NULLCHAR,
  596.         "translate",dotranslate,0,    0, NULLCHAR,
  597.         "verbose",  doverbose,  0,    0, NULLCHAR,
  598. #ifdef ENH
  599.         "zoneinit", dozoneinit, 1024, 2, "domain zoneinit <server> [<filename>]",
  600. #endif
  601.         NULLCHAR,    NULLFP,        0,    0, NULLCHAR,
  602.     };
  603.     return subcmd(Dcmds,argc,argv,p);
  604. }
  605.  
  606.